﻿<script setup lang="ts" name="">
import { useResizeObserver, useDebounceFn } from '@vueuse/core'
import { storeToRefs } from 'pinia'
import { useSystemConfigStore } from '@/store/storage/systemConfigStore'
import draggable from 'vuedraggable'
import { DEF_FILE_NAME } from './Export2Excel'

const systemConfigStore = useSystemConfigStore()
const { systemConfig } = storeToRefs(systemConfigStore)
const dialogVisible = ref(false)

const props = defineProps({
  fieldList: { type: Array as any },
  hasSelected: { type: Boolean }
})

// 打开弹窗
const handleOpenDialog = () => {
  dialogVisible.value = true
  setTimeout(() => {
    getModalHeight()
  }, 200)
}
// 关闭弹窗
const handleCloseDialog = () => {
  dialogVisible.value = false
}
// 子组件将方法暴露给父组件
defineExpose({ handleOpenDialog })

// 最大化效果
const fullscreen = ref(false)
// 最大化点击事件
const maxSizeHandle = () => {
  fullscreen.value = !fullscreen.value
}
// 监听最大化事件
watch(
  () => fullscreen.value,
  () => {
    getModalHeight()
  }
)
const modalHeight = ref(0)
// 监听元素尺寸变化
useResizeObserver(
  document.body,
  useDebounceFn(() => {
    getModalHeight()
  }, 200)
)
const modalHeader = ref(null)
const modalFooter = ref(null)
// 获取当前的表格的最大高度
const getModalHeight = () => {
  if (dialogVisible.value) {
    const rect = document.body.getBoundingClientRect()
    if (fullscreen.value) {
      modalHeight.value = rect.height - modalHeader.value.offsetHeight - modalFooter.value.offsetHeight - 15 * 2 - systemConfig.value.space * 2 - 2
    } else {
      modalHeight.value = rect.height * 0.7 - modalHeader.value.offsetHeight - modalFooter.value.offsetHeight - 15 * 2 - systemConfig.value.space * 2 - 2
    }
  }
}

const emit = defineEmits(['success'])

const handleOk = () => {
  const sortArr = []
  const headerObj = {}
  fieldsList.value.forEach((item) => {
    if (checkedFields.value.includes(item.key)) {
      sortArr.push(item.key)
      headerObj[item.key] = item.value
    }
  })
  emit('success', {
    filename: `${exportInfo.value.filename === '' ? DEF_FILE_NAME.split('.')[0] : exportInfo.value.filename}.${exportInfo.value.fileType}`,
    fileType: exportInfo.value.fileType,
    dataScope: exportInfo.value.dataScope,
    header: headerObj,
    sort: sortArr,
    headerType: exportInfo.value.headerType
  })
  handleCloseDialog()
}

const exportInfo = ref({
  filename: '',
  fileType: 'xlsx',
  dataScope: 1,
  headerType: 'default'
})

const checkAllField = ref(false)
const isIndeterminate = ref(false)
const checkedFields = ref([])
const fieldsList = ref(props.fieldList || [])

const handleCheckAllChange = (val: boolean) => {
  checkedFields.value = []
  fieldsList.value.forEach((item) => {
    if (val) {
      checkedFields.value.push(item.key)
    }
  })
  isIndeterminate.value = false
  console.log(checkedFields.value)
}
const handleCheckedFieldsChange = (value: string[]) => {
  const checkedCount = value.length
  checkAllField.value = checkedCount === props.fieldList.length
  isIndeterminate.value = checkedCount > 0 && checkedCount < props.fieldList.length
  console.log(checkedFields.value)
}
</script>

<template>
  <el-dialog v-model="dialogVisible" width="600px" append-to-body destroy-on-close :fullscreen="fullscreen" :show-close="false" :before-close="handleCloseDialog">
    <template #header>
      <div class="modal-header" ref="modalHeader">
        <div class="header-title">{{ $t('moduleTitle.moduleTitleExport') }}</div>
        <el-tooltip :content="fullscreen ? $t('buttons.buttonRestoreDown') : $t('buttons.buttonMaximize')" placement="bottom">
          <el-button size="small" @click="maxSizeHandle"><svg-icon :icon="fullscreen ? 'bi:fullscreen-exit' : 'bi:fullscreen'"></svg-icon></el-button>
        </el-tooltip>
        <el-tooltip :content="$t('buttons.buttonClose')" placement="bottom">
          <el-button size="small" @click="handleCloseDialog"><svg-icon icon="ep:close"></svg-icon></el-button>
        </el-tooltip>
      </div>
    </template>
    <div class="export-modal__body">
      <el-scrollbar :style="{ height: modalHeight + 'px' }">
        <el-form>
          <el-form-item :label="$t('exportModal.fileName')" prop="filename">
            <el-input v-model="exportInfo.filename" clearable />
          </el-form-item>
          <el-form-item :label="$t('exportModal.fileType')">
            <el-select v-model="exportInfo.fileType" placeholder="">
              <el-option :label="$t('exportModal.fileTypeXlsx')" value="xlsx" />
              <el-option :label="$t('exportModal.fileTypeCsv')" value="csv" />
              <el-option :label="$t('exportModal.fileTypeHtml')" value="html" />
              <el-option :label="$t('exportModal.fileTypeXml')" value="xml" />
              <el-option :label="$t('exportModal.fileTypeTxt')" value="txt" />
            </el-select>
          </el-form-item>
          <el-form-item :label="$t('exportModal.dataScope')">
            <el-select v-model="exportInfo.dataScope" placeholder="">
              <el-option :label="$t('exportModal.dataScopeCurrentPage')" :value="1" />
              <el-option :label="$t('exportModal.dataScopeSelected')" :value="2" :disabled="!props.hasSelected" />
              <el-option :label="$t('exportModal.dataScopeAll')" :value="3" />
            </el-select>
          </el-form-item>
          <el-form-item :label="$t('exportModal.headerType')">
            <el-radio-group class="radio-button" v-model="exportInfo.headerType">
              <el-radio-button label="default">{{ $t('exportModal.headerTypeDefault') }}</el-radio-button>
              <el-radio-button label="custom">{{ $t('exportModal.headerTypeCustom') }}</el-radio-button>
            </el-radio-group>
          </el-form-item>
          <el-form-item :label="$t('exportModal.fields')">
            <div class="field-list flex-1 m-6px">
              <div class="all-field">
                <el-checkbox v-model="checkAllField" :indeterminate="isIndeterminate" @change="handleCheckAllChange">
                  {{
                    $t('exportModal.allFields') }}
                </el-checkbox>
              </div>
              <el-checkbox-group v-model="checkedFields" @change="handleCheckedFieldsChange">
                <draggable :list="fieldsList" :item-key="(key) => key" animation="300" handle=".move">
                  <template #item="{ element }">
                    <div class="item-field">
                      <span class="move"><svg-icon icon="ri:drag-move-2-fill"></svg-icon></span>
                      <el-checkbox :label="element.key">{{ element.value }}</el-checkbox>
                    </div>
                  </template>
                </draggable>
              </el-checkbox-group>
            </div>
          </el-form-item>
        </el-form>
      </el-scrollbar>
    </div>
    <template #footer>
      <span class="modal-footer" ref="modalFooter">
        <el-button @click="handleCloseDialog">{{ $t('buttons.buttonCancel') }}</el-button>
        <el-button type="primary" @click="handleOk">{{ $t('buttons.buttonConfirm') }}</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<style scoped lang="scss">
.modal-header {
  display: flex;
  margin: -15px calc(0px - var(--el-space));
  padding: 15px var(--el-space);

  .header-title {
    flex: 1;
    height: 24px;
    line-height: 24px;
  }

  .el-button {
    margin-left: 0;
    background: none !important;
    border: none !important;

    &:hover,
    &:focus {
      background: none;
    }
  }
}

.modal-footer {
  display: inline-flex;
  overflow: hidden;
}

.el-dialog {
  :deep(.el-dialog__body) {
    padding: 0;
  }
}

.export-modal__body {
  margin: calc(0px - var(--el-space));
  overflow: hidden;

  :deep(.el-scrollbar__view) {
    padding: var(--el-space);
  }
}

.field-list {
  border: 1px solid var(--el-border-color-lighter);

  .all-field {
    padding-left: 36px;
    background: var(--el-fill-color-light);
    border-bottom: 1px solid var(--el-border-color-lighter);
  }

  .el-checkbox-group {
    padding: 6px 0;
  }

  .item-field {
    display: flex;
    align-items: center;

    .move {
      padding: 0 10px;
      font-size: 14px;
      cursor: move;

      .el-icon {
        color: var(--el-text-color-secondary);
      }
    }
  }
}
</style>
